from flask import Blueprint, request
from flask import jsonify
from sqlalchemy.exc import SQLAlchemyError

from db.controller.db_controller import db_controller
from enums.protocol_type import ProtocolType
from web.log import log
from web.model.device import CreateDevice, EditDevice, DeviceName
from service.client_manager import client_manager

# 创建蓝图对象
device_blueprint = Blueprint('device', __name__)


@device_blueprint.route('/device/add_device', methods=['POST'])
def add_device():
    body = CreateDevice(**request.get_json())

    device_name = body.device_name
    ip = body.ip
    port = body.port
    protocol = body.protocol
    try:
        if db_controller.device_dao.add_device(device_name, ip, port, protocol):
            if protocol == ProtocolType.TCP:
                client_manager.add_modbus_tcp_client(device_name, ip, port)
            elif protocol == ProtocolType.RTU_OVER_TCP:
                client_manager.add_modbus_rtu_over_tcp_client(device_name, ip, port)
            return jsonify({'status': 200, 'msg': '添加设备成功', 'data': True})
        else:
            return jsonify({'status': 500, 'msg': '添加设备失败', 'data': False})
    except SQLAlchemyError as e:
        log.error(f"数据库操作失败: {e}")
        return jsonify({'status': 500, 'msg': f'数据库错误: {e}', 'data': False})
    except Exception as e:
        log.error(f"未知错误: {e}")
        return jsonify({'status': 500, 'msg': f'服务器内部错误: {e}', 'data': False})


@device_blueprint.route('/device/edit_device', methods=['POST'])
def edit_device():
    body = EditDevice(**request.get_json())

    device_id = body.device_id
    device_name = body.device_name
    ip = body.ip
    port = body.port
    protocol = body.protocol
    try:
        old_device = db_controller.device_dao.get_device_by_id(device_id)
        old_device_name = old_device.get('name')
        if db_controller.device_dao.edit_device(device_id, device_name, ip, port, protocol):
            client_manager.edit_client(old_device_name, device_name, protocol, ip, port)
            return jsonify({'status': 200, 'msg': '修改设备成功', 'data': True})
        else:
            return jsonify({'status': 500, 'msg': '修改设备失败', 'data': False})
    except SQLAlchemyError as e:
        log.error(f"数据库操作失败: {e}")
        return jsonify({'status': 500, 'msg': f'数据库错误: {e}', 'data': False})
    except Exception as e:
        log.error(f"未知错误: {e}")
        return jsonify({'status': 500, 'msg': f'服务器内部错误: {e}', 'data': False})


@device_blueprint.route('/device/delete_device', methods=['POST'])
def delete_device():
    device_name = DeviceName(**request.get_json()).device_name
    try:
        if db_controller.device_dao.delete_device(device_name):
            client_manager.delete_client(device_name)
            return jsonify({'status': 200, 'msg': '删除设备成功', 'data': True})
        else:
            return jsonify({'status': 500, 'msg': '删除设备失败', 'data': False})
    except SQLAlchemyError as e:
        log.error(f"数据库操作失败: {e}")
        return jsonify({'status': 500, 'msg': f'数据库错误: {e}', 'data': False})
    except Exception as e:
        log.error(f"未知错误: {e}")
        return jsonify({'status': 500, 'msg': f'服务器内部错误: {e}', 'data': False})


@device_blueprint.route('/device/get_device_list', methods=['GET'])
def get_device_list():
    try:
        device_list = db_controller.device_dao.get_device_list()
        return jsonify({'status': 200, 'msg': '获取设备列表成功!', 'data': device_list})
    except Exception as e:
        log.error(e)
        return jsonify({'status': 500, 'msg': f'服务器内部错误: {e}!', 'data': True})


@device_blueprint.route('/device/get_latest_message', methods=['POST'])
def get_latest_message():
    device_name = DeviceName(**request.get_json()).device_name
    try:
        client = client_manager.get_client(device_name)
        if client:
            message = client.get_latest_message()
            return jsonify({'status': 200, 'msg': '获取最新报文成功!', 'data': message})
        else:
            return jsonify({'status': 500, 'msg': '获取最新报文失败, 设备不存在!', 'data': []})
    except Exception as e:
        log.error(e)
        return jsonify({'status': 500, 'msg': f'获取最新报文失败, 服务器内部错误 {e}!', 'data': []})
